package root.electronclass.electronclass.grade.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Shader
import android.graphics.Typeface
import android.util.AttributeSet
import android.view.View
import androidx.core.graphics.toColorInt

/**
 * 横条柱状图图表
 * @author Lokiy
 * @date 2025/6/11 21:23
 */
class SlantBarChartView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : View(context, attrs) {

    private val items = mutableListOf<SubjectBarItem>()
    private var barHeight = 64f
    private var barSpace = 32f
    private val barRadius = 16f
    private var slantWidth = 40f

    private val blueGradient = intArrayOf("#B3E6FF".toColorInt(), "#59AEF3".toColorInt())
    private val orangeGradient = intArrayOf("#FFD6B3".toColorInt(), "#FF9B5E".toColorInt())

    private val labelPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = "#093b5d".toColorInt()
        textSize = 18f
    }
    private val countPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = "#093b5d".toColorInt()
        textSize = 24f
        typeface = Typeface.DEFAULT_BOLD
    }
    private val timesPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = "#093b5d".toColorInt()
        textSize = 18f
    }
    private val path = Path()
    private val barPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    init {
        if (isInEditMode) {
            setData(
                listOf(
                    SubjectBarItem("数学", 6),
                    SubjectBarItem("语文", 5),
                    SubjectBarItem("英语", 5),
                    SubjectBarItem("科目", 5),
                    SubjectBarItem("科目", 5),
                    SubjectBarItem("科目", 3),
                    SubjectBarItem("科目", 1),
                    SubjectBarItem("科目", 1)
                )
            )
        }
    }

    fun setData(data: List<SubjectBarItem>) {
        items.clear()
        items.addAll(data)
        invalidate()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        if (items.isNotEmpty()) {
            val itemHeight = measuredHeight / items.size
            barHeight = itemHeight * 0.55f
            barSpace = itemHeight * 0.45f
            slantWidth = barHeight / 2f
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (items.isEmpty()) return

        val maxCount = items.maxOf { it.count }.coerceAtLeast(1)
        val barMaxWidth = width * 0.8f

        for ((i, item) in items.withIndex()) {
            val top = paddingTop + i * (barHeight + barSpace) + barSpace / 2
            val left = paddingLeft.toFloat()
            val right = left + barMaxWidth * item.count / maxCount
            val bottom = top + barHeight

            // 渐变色
            val startColor = if (i % 2 == 0) blueGradient[0] else orangeGradient[0]
            val endColor = if (i % 2 == 0) blueGradient[1] else orangeGradient[1]
            val shader = LinearGradient(0f, top, right, top, startColor, endColor, Shader.TileMode.CLAMP)
            barPaint.shader = shader

            // 斜切 path
            val path = path.apply {
                reset()
                moveTo(left, top)
                lineTo(right, top)
                lineTo(right - slantWidth, bottom)
                lineTo(left, bottom)
                close()
            }
            canvas.drawPath(path, barPaint)

            val barCenterY = top + barHeight / 2

            // 科目名
            val labelY = barCenterY - (labelPaint.descent() + labelPaint.ascent()) / 2
            canvas.drawText(item.label, left + 12f, labelY, labelPaint)

            // 次数
            val countText = "${item.count}"
            val countX = right + 4f
            val countY = barCenterY - (countPaint.descent() + countPaint.ascent()) / 2
            canvas.drawText(countText, countX, countY, countPaint)

            // “次”
            val timesX = countX + countPaint.measureText(countText) + 2f
            val timesY = barCenterY - (timesPaint.descent() + timesPaint.ascent()) / 2
            canvas.drawText("次", timesX, timesY, timesPaint)
        }
    }
}

data class SubjectBarItem(
    val label: String,
    val count: Int,
)